package godzilla.ciudad;

import org.json.JSONObject;
import org.json.JSONString;

import godzilla.ciudad.estructuras.Estructura;
import godzilla.ciudad.estructuras.NoSePuedeConstruirAquiException;
import godzilla.ciudad.estructuras.Superficie;

public class Plano implements JSONString {
	
	private Superficie[][] matriz;
	private int dimensionX;
	private int dimensionY;


	public Plano(int dimensionX, int dimensionY){
		
		this.dimensionX=dimensionX + 1;
		this.dimensionY=dimensionY + 1;
		
		this.matriz = new Superficie[dimensionX + 1][dimensionY + 1];
		
		for(int i=1;i<=dimensionX;i++){
			for(int j=1;j<=dimensionY;j++){
				this.matriz[i][j] = new Superficie();
			}
		}
		
		for(int i=1;i<=dimensionX;i++){
			for(int j=1;j<=dimensionY;j++){
				
				if (i<dimensionX) this.matriz[i][j].vincularCon( this.matriz[i+1][j] , new DireccionEste());
				if (j<dimensionY) this.matriz[i][j].vincularCon( this.matriz[i][j+1] , new DireccionSur());

			}
		}
		
	}


	public Superficie verSuperficieEn(Punto punto) {
		
		if(punto.x()>=dimensionX || punto.y()>=dimensionY){
			return null;
		}
		
		return this.matriz[punto.x()][punto.y()];

	}


	public void construir(Estructura estructura, Punto punto) throws NoSePuedeConstruirAquiException {
		
		this.matriz[punto.x()][punto.y()].construir(estructura);
		
	}


	public int dimensionX() {
		return dimensionX;
	}


	public int dimensionY() {

		return dimensionY;
	}


	public static Plano obtenerObjetoDesdeJSON(String string) {
		
		JSONObject objetoJSON = new JSONObject(string);
		int dimensionX = objetoJSON.getInt("DimensionX");
		int dimensionY = objetoJSON.getInt("DimensionY");
		Plano planoRecuperado = new Plano(dimensionX, dimensionY);
		JSONObject objetoMatrizJSON = objetoJSON.getJSONObject("Matriz");
		llenarMatriz(planoRecuperado,dimensionX,dimensionY,objetoMatrizJSON);
		
		return planoRecuperado;
	}


	private static void llenarMatriz(Plano planoRecuperado, int dimensionX, int dimensionY,JSONObject matrizJSON) {
		
		for (int x=1;x < dimensionX; x++){
			for(int y=1;y< dimensionY; y++){
				Punto punto = new Punto(x,y);
				JSONObject superficieJSON = matrizJSON.getJSONObject(punto.aTexto());
				Superficie superficie = Superficie.obtenerObjetoDesdeJSON(superficieJSON.toString());
				planoRecuperado.matriz[x][y] = superficie;
			}
		}
		
		for(int i=1;i<dimensionX;i++){
			for(int j=1;j<dimensionY;j++){
				
				if (i<dimensionX) planoRecuperado.matriz[i][j].vincularCon( planoRecuperado.matriz[i+1][j] , new DireccionEste());
				if (j<dimensionY) planoRecuperado.matriz[i][j].vincularCon( planoRecuperado.matriz[i][j+1] , new DireccionSur());

			}
		}
		
		
		
	}


	@Override
	public String toJSONString() {
		
		JSONObject objetoJSON = new JSONObject();
		objetoJSON.put("DimensionX", dimensionX);
		objetoJSON.put("DimensionY", dimensionY);
		
		JSONObject matrizJSON = new JSONObject();
		
		for (int x=1;x < dimensionX; x++){
			for(int y=1;y< dimensionY; y++){
				Punto punto = new Punto(x,y);
				JSONObject superficieJSON = new JSONObject(this.matriz[x][y].toJSONString());
				matrizJSON.put(punto.aTexto(), superficieJSON);
			}
		}
		
		objetoJSON.put("Matriz", matrizJSON);
		
		
		
		
		return objetoJSON.toString();
		
	}

}
